from flask import Blueprint, jsonify, request
from flasgger import swag_from
from app.utils.decorators import admin_required
from app.utils.response import success_response, error_response
from app.models import Activity, Venue, User
from app.models.order import Order
from app.models.activity import ActivityParticipant
from app import db
from sqlalchemy import func, desc
from datetime import datetime, timedelta
from app.api.v1.docs.dashboard_docs import (
    GET_DASHBOARD_STATS_DOC, GET_ORDER_TREND_DOC, 
    GET_VENUE_BOOKINGS_DOC, GET_RECENT_ORDERS_DOC
)

dashboard_bp = Blueprint('dashboard', __name__)

@dashboard_bp.route('/stats', methods=['GET'])
@admin_required
@swag_from(GET_DASHBOARD_STATS_DOC)
def get_dashboard_stats():
    """获取仪表盘统计数据"""
    try:
        # 总活动数
        total_activities = Activity.query.count()
        
        # 本月活动数
        current_month = datetime.now().replace(day=1)
        month_activities = Activity.query.filter(
            Activity.created_at >= current_month
        ).count()
        
        # 总场馆数
        total_venues = Venue.query.count()
        
        # 总用户数
        total_users = User.query.count()
        
        # 本月新用户数
        month_users = User.query.filter(
            User.created_at >= current_month
        ).count()
        
        # 活跃场馆数（本月有活动的场馆）
        active_venues = db.session.query(func.count(func.distinct(Activity.venue_id))).filter(
            Activity.created_at >= current_month
        ).scalar() or 0
        
        # 总订单数
        total_orders = Order.query.count()
        
        # 本月订单数
        month_orders = Order.query.filter(
            Order.created_at >= current_month
        ).count()
        
        # 今日订单数
        today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
        today_orders = Order.query.filter(
            Order.created_at >= today
        ).count()
        
        # 今日活动数（今日开始的活动）
        today_activities = Activity.query.filter(
            Activity.start_time >= today,
            Activity.start_time < today + timedelta(days=1)
        ).count()
        
        # 今日收入（今日已支付的订单）
        today_revenue = db.session.query(func.sum(Order.amount)).filter(
            Order.created_at >= today,
            Order.status.in_([1, 3])  # 已支付和已完成的订单
        ).scalar() or 0
        
        # 本月收入
        month_revenue = db.session.query(func.sum(Order.amount)).filter(
            Order.created_at >= current_month,
            Order.status.in_([1, 3])  # 已支付和已完成的订单
        ).scalar() or 0
        
        # 总收入
        total_revenue = db.session.query(func.sum(Order.amount)).filter(
            Order.status.in_([1, 3])
        ).scalar() or 0
        
        # 预计总收入（包含所有订单，含未支付）
        expected_revenue = db.session.query(func.sum(Order.amount)).filter(
            Order.status.in_([0, 1, 3])  # 未支付、已支付、已完成的订单
        ).scalar() or 0
        
        # 活动参与总数
        total_participants = ActivityParticipant.query.filter_by(status='joined').count()
        
        # 本月活动参与数
        month_participants = ActivityParticipant.query.filter(
            ActivityParticipant.joined_at >= current_month,
            ActivityParticipant.status == 'joined'
        ).count()
        
        stats = {
            'total_activities': total_activities,
            'month_activities': month_activities,
            'today_activities': today_activities,
            'total_venues': total_venues,
            'active_venues': active_venues,
            'total_users': total_users,
            'month_users': month_users,
            'total_orders': total_orders,
            'month_orders': month_orders,
            'today_orders': today_orders,
            'total_revenue': float(total_revenue),
            'month_revenue': float(month_revenue),
            'today_revenue': float(today_revenue),
            'expected_revenue': float(expected_revenue),
            'total_participants': total_participants,
            'month_participants': month_participants,
            'activity_growth': round((month_activities / max(total_activities - month_activities, 1)) * 100, 1) if total_activities > month_activities else 0,
            'user_growth': round((month_users / max(total_users - month_users, 1)) * 100, 1) if total_users > month_users else 0,
            'order_growth': round((month_orders / max(total_orders - month_orders, 1)) * 100, 1) if total_orders > month_orders else 0,
            'revenue_growth': round((float(month_revenue) / max(float(total_revenue) - float(month_revenue), 1)) * 100, 1) if total_revenue > month_revenue else 0
        }
        
        return success_response(data=stats)
        
    except Exception as e:
        return error_response(f"获取统计数据失败: {str(e)}")

@dashboard_bp.route('/charts/order-trend', methods=['GET'])
@admin_required
@swag_from(GET_ORDER_TREND_DOC)
def get_order_trend():
    """获取订单趋势图表数据"""
    try:
        period = request.args.get('period', 'week')  # week 或 month
        
        if period == 'week':
            # 最近7天的订单数据
            days = []
            orders = []
            
            for i in range(7):
                day = datetime.now() - timedelta(days=i)
                day_start = day.replace(hour=0, minute=0, second=0, microsecond=0)
                day_end = day_start + timedelta(days=1)
                
                day_orders = Order.query.filter(
                    Order.created_at >= day_start,
                    Order.created_at < day_end
                ).count()
                
                days.insert(0, day.strftime('%m/%d'))
                orders.insert(0, day_orders)
                
        else:  # month
            # 最近30天的订单数据
            days = []
            orders = []
            
            for i in range(30):
                day = datetime.now() - timedelta(days=i)
                day_start = day.replace(hour=0, minute=0, second=0, microsecond=0)
                day_end = day_start + timedelta(days=1)
                
                day_orders = Order.query.filter(
                    Order.created_at >= day_start,
                    Order.created_at < day_end
                ).count()
                
                days.insert(0, day.strftime('%m/%d'))
                orders.insert(0, day_orders)
        
        return success_response({
            'categories': days,
            'data': orders,
            'period': period
        })
        
    except Exception as e:
        return error_response(f"获取订单趋势失败: {str(e)}")

@dashboard_bp.route('/charts/venue-bookings', methods=['GET'])
@admin_required
@swag_from(GET_VENUE_BOOKINGS_DOC)
def get_venue_bookings():
    """获取场馆预约情况图表数据"""
    try:
        # 获取各场馆的订单数量（最近30天）
        thirty_days_ago = datetime.now() - timedelta(days=30)
        
        venue_data = db.session.query(
            Venue.name,
            func.count(Order.id).label('order_count')
        ).join(Order, Venue.id == Order.venue_id)\
         .filter(Order.created_at >= thirty_days_ago)\
         .group_by(Venue.id, Venue.name)\
         .order_by(func.count(Order.id).desc())\
         .limit(10).all()
        
        # 构建图表数据
        venue_names = []
        booking_counts = []
        
        for venue_name, order_count in venue_data:
            venue_names.append(venue_name)
            booking_counts.append(order_count)
        
        # 构建饼图数据
        pie_data = []
        for i, (name, count) in enumerate(zip(venue_names, booking_counts)):
            pie_data.append({
                'name': name,
                'value': count
            })
        
        return success_response({
            'venue_names': venue_names,
            'booking_counts': booking_counts,
            'pie_data': pie_data
        })
        
    except Exception as e:
        return error_response(f"获取场馆预约数据失败: {str(e)}")

@dashboard_bp.route('/orders/recent', methods=['GET'])
@admin_required
@swag_from(GET_RECENT_ORDERS_DOC)
def get_recent_orders():
    """获取最近的订单"""
    try:
        # 使用原生SQL查询来避免ORM的类型转换问题
        sql = """
        SELECT 
            o.id, o.order_no, o.status, o.amount,
            o.created_at, o.reservation_date, 
            o.start_time, o.end_time,
            v.name as venue_name,
            u.nickname as user_name
        FROM orders o
        LEFT JOIN venues v ON o.venue_id = v.id
        LEFT JOIN users u ON o.user_id = u.id
        ORDER BY o.id DESC
        LIMIT 10
        """
        
        result = db.session.execute(db.text(sql))
        orders = []
        
        for row in result:
            orders.append({
                'id': row.id,
                'order_no': row.order_no,
                'type': '场馆预订',
                'status': row.status,
                'status_text': {0: '未支付', 1: '已支付', 2: '已取消', 3: '已完成', 4: '已退款'}.get(row.status, '未知'),
                'amount': float(row.amount) if row.amount else 0,
                'create_time': str(row.created_at) if row.created_at else None,
                'venue_name': row.venue_name or '未知场馆',
                'user_name': row.user_name or '未知用户',
                'reservation_date': str(row.reservation_date) if row.reservation_date else None,
                'time_slot': f"{row.start_time}-{row.end_time}" if row.start_time and row.end_time else '未知时间'
            })
        
        return success_response(data=orders)
        
    except Exception as e:
        return error_response(f"获取最近订单失败: {str(e)}") 